home *** CD-ROM | disk | FTP | other *** search
/ Gigantic Games 2 / Gigantic Games 2.iso / pc / _z_ / zorkmachine / io.c < prev    next >
C/C++ Source or Header  |  1994-12-23  |  10KB  |  584 lines

  1. /*
  2. *    @(#)io.c    2.24
  3. */
  4.  
  5. # ifdef OSK
  6. # include <modes.h>
  7. # endif
  8. # include "zmachine.h"
  9. # include "keys.h"
  10.  
  11. char    *iovers = "122400";
  12. int    pfile = -1;
  13. FILE    *fopen();
  14. #ifdef AMIGA
  15. char print_name[256] = "prt:";
  16. #else
  17. char print_name[256] = "protocol";
  18. #endif
  19. int printer_width = 80;
  20.  
  21. /*****************************************************************************/
  22.  
  23. struct dev *init_dev(out, crlf, l, h, wrap)
  24. void (*out)(); void (*crlf)(); int l, h, wrap;
  25. {
  26.     register struct dev *d;
  27.  
  28.     if (d = (struct dev *)malloc(sizeof(struct dev) + l))
  29.     {
  30.         d->buffer = d->bp = (char *)d + sizeof(struct dev);
  31.         d->width = l;
  32.         d->height = h;
  33.         d->count = 0;
  34.         d->out_f = out;
  35.         d->crlf_f = crlf;
  36.         d->wrap = wrap;
  37.         return(d);
  38.     }
  39.     else
  40.         no_mem_error();
  41. }
  42.  
  43. void putc_dev(c, d)
  44. char c; register struct dev *d;
  45. {
  46.     register char *s, *p;
  47.  
  48.     if (c == '\n' || c == FLUSH)
  49.     {
  50.         (*d->out_f)(d->buffer, d->bp);
  51.         if (c != FLUSH && (d->count != d->width || !d->wrap))
  52.             (*d->crlf_f)();
  53.  
  54.         con_flush();
  55.  
  56.         d->count = 0;
  57.         d->bp = d->buffer;
  58.     }
  59.     else
  60.     {
  61.         if (d->width < d->count+1)
  62.         {
  63.             if (c == ' ')
  64.             {
  65.                 (*d->out_f)(d->buffer, d->bp);
  66.                 if (d->count != d->width || !d->wrap)
  67.                     (*d->crlf_f)();
  68.                 d->count = 0;
  69.                 d->bp = d->buffer;
  70.                 return;
  71.             }
  72.             else
  73.             {
  74.                 for(s = d->bp; --s > d->buffer;)
  75.                     if (*s == ' ')
  76.                         break;
  77.  
  78.                 if (s == d->buffer)
  79.                 {
  80.                     (*d->out_f)(d->buffer, d->bp);
  81.                     d->count = 0;
  82.                     d->bp = d->buffer;
  83.                 }
  84.                 else
  85.                 {
  86.                     (*d->out_f)(d->buffer, s);
  87.                     (*d->crlf_f)();
  88.                     for (d->count = 0, p = d->buffer;
  89.                              s < d->bp-1;
  90.                                 d->count++)
  91.                         *p++ = *++s;
  92.                     d->bp = p;
  93.                 }
  94.             }
  95.  
  96.         }
  97.         *(d->bp++) = c;
  98.         d->count++;
  99.     }
  100. }
  101.  
  102. void output_chr(c)
  103. char c;
  104. {
  105.     extern int use_line, in_status;
  106.     extern char *line;
  107.  
  108.     if (c == FLUSH)
  109.         putc_dev(c, screen);
  110.     else if (use_line)
  111.         *line++ = c;
  112.     else
  113.     {
  114.         if (c == 9)
  115.             c = ' ';
  116.  
  117.         putc_dev(c, screen);
  118.  
  119.         if (!in_status && (word_get(main_h->reserved5) & 1))
  120.             putc_dev(c, printer);
  121.     }
  122. }
  123.  
  124. void output_str(p)
  125. register char *p;
  126. {
  127.     while(*p)
  128.         output_chr(*p++);
  129. }
  130.  
  131. void output_status(room, score)
  132. char *room, *score;
  133. {
  134.     register int i,t;
  135.     int x,y;
  136.  
  137. #ifdef AMIGA
  138.     STATIC char BackupRoom[80],BackupScore[80];
  139.  
  140.     if(room)
  141.         strcpy(BackupRoom,room);
  142.     else
  143.         room = BackupRoom;
  144.  
  145.     if(score)
  146.         strcpy(BackupScore,score);
  147.     else
  148.         score = BackupScore;
  149. #endif
  150.  
  151.     storeXY(&x, &y);
  152.     cursorOFF();
  153.     gotoXY(0,0);
  154.     reverseON();
  155.     con_str1(room);
  156.  
  157.     t = screen->width - strlen(score);
  158.     for(i = strlen(room); i < t; i++)
  159.         con_chr(' ');
  160.  
  161.     con_str1(score);
  162.     reverseOFF();
  163.     cursorON();
  164.     gotoXY(x,y);
  165. }
  166.  
  167. /*****************************************************************************/
  168.  
  169. void more_test()
  170. {
  171.     char getc_ne();
  172.     extern int line_cnt, status_len;
  173.  
  174.     if ((screen->height - status_len) == ++line_cnt)
  175.     {
  176.         status();
  177.         con_str1("[More]");
  178.         con_flush();
  179.         con_getc();
  180.         con_str1("\r      \r");
  181.         line_cnt = 2;
  182.     }
  183. }
  184.  
  185. void scr_write(a,b)
  186. char *a, *b;
  187. {
  188.     extern int in_status;
  189.  
  190.     if (!in_status)
  191.         more_test();
  192.  
  193.     if (b > a)
  194.         con_str2(a,b);
  195.  
  196. #ifdef AMIGA
  197.     SayMore(a,b);
  198. #endif
  199. }
  200.  
  201. int prot_open()
  202. {
  203.     if (pfile == -1)
  204.     {
  205. #ifdef OSK
  206.         if ((pfile = creat(print_name, S_IREAD|S_IWRITE)) < 0)
  207. #else
  208.         if ((pfile = creat(print_name, 0666)) < 0)
  209. #endif
  210.         {
  211.             con_crlf();
  212.             con_str1("Can't open protocol file");
  213.             con_crlf();
  214.             pfile = -2;
  215.         }
  216.     }
  217.     return(pfile >= 0);
  218. }
  219.  
  220. void prot_write(a,b)
  221. char *a, *b;
  222. {
  223.     if (prot_open() && (b > a))
  224.         write(pfile, a, b-a);
  225. }
  226.  
  227. void prot_crlf()
  228. {
  229.     if (prot_open())
  230. # if defined(unix) || defined(OSK)
  231.         write(pfile, "\n", 1);
  232. # else
  233. #ifdef AMIGA
  234.         write(pfile, "\n", 1);
  235. #else
  236.         write(pfile, "\r\n", 2);
  237. #endif
  238. # endif
  239. }
  240.  
  241. /*****************************************************************************/
  242.  
  243. char fkeys[10][17];
  244.  
  245. int save_keys()
  246. {
  247.     extern int save_len;
  248.     return(write_saveb(save_len + 1, 170, fkeys));
  249. }
  250.  
  251. int restore_keys()
  252. {
  253.     extern int save_len;
  254.     return(read_saveb(save_len + 1, 170, fkeys));
  255. }
  256.  
  257. char *read_str(p, hist)
  258. char *p; struct hist_buf *hist;
  259. {
  260.     extern int line_cnt;
  261.     register char *q, *src, *dst;
  262.     char *retype;
  263.     char *end;
  264.     register int c;
  265.     register int i, e;
  266.     int x, y;
  267.  
  268.     static char fbuf[18];
  269.     static char fhmem[36];
  270.     static struct hist_buf fhist = {36, fhmem, fhmem};
  271.     static int imode=1;
  272.     static int init=1;
  273.     static int fprog = 0;
  274.  
  275.     if (init)
  276.     {
  277.         init = 0;
  278.         fhmem[0] = fhmem[1] = '\0';
  279.  
  280.         for(i = F01; i < F10; i++)
  281.             fkeys[i][0] = '\0';
  282.     }
  283.  
  284.     retype = NULL;
  285.     con_flush();
  286.  
  287.     (*p)--;            /* we need one char more (for '\0')    */
  288.     line_cnt = 1;
  289.     p[1] = '\0';
  290.     end = p + p[0] + 1;
  291.     q = p + 1;
  292.     while ((c = con_getc()) != RETURN)
  293.     {
  294.         switch(c)
  295.         {
  296.             case CUP:
  297.             case CDOWN:
  298.                 if (c == CUP)
  299.                 {
  300.                     if (!retype)
  301.                         retype = hist->undo;
  302.                     else if (*(retype + strlen(retype) + 1))
  303.                         retype += strlen(retype) + 1;
  304.                     else
  305.                         break;
  306.                 }
  307.                 else
  308.                 {
  309.                     if (!retype)
  310.                         retype = hist->undo;
  311.                     else if (retype != hist->hb)
  312.                         for (retype -= 1;
  313.                           retype != hist->hb &&
  314.                             retype[-1]; retype--)
  315.                             ;
  316.                     else
  317.                         break;
  318.                 }
  319.  
  320.             case RETYPE:
  321.                 if (!retype)
  322.                     retype = hist->undo;
  323.  
  324.                 /* go to start of input line */
  325.                 e = q - p - 1;
  326.                 cursorOFF();
  327.                 for(i = 0; i < e; i++)
  328.                     cursorLEFT();
  329.  
  330.                 /* delete to end of input line */
  331.                 storeXY(&x, &y);
  332.                 e = strlen(p+1);
  333.                 for (i = 0; i < e; i++)
  334.                     con_chr(' ');
  335.                 gotoXY(x, y);
  336.  
  337.                 /* copy old input line and print it */
  338.                 strncpy(p + 1, retype, *p);
  339.                 *(p + *p + 1) = '\0';
  340.                 con_str1(p + 1);
  341.                 cursorON();
  342.                 q = p + 1 + strlen(p + 1);
  343.                 break;
  344.  
  345.             case CLEFT:
  346.                 if (q > p + 1)
  347.                 {
  348.                     q--;
  349.                     cursorLEFT();
  350.                 }
  351.                 break;
  352.  
  353.             case CRIGHT:
  354.                 if (*q != '\0')
  355.                     con_chr(*q++);
  356.                 break;
  357.  
  358.             case START:
  359.                 e = q - p - 1;
  360.                 cursorOFF();
  361.                 for(i = 0; i < e; i++)
  362.                     cursorLEFT();
  363.                 cursorON();
  364.                 q = p + 1;
  365.                 break;
  366.  
  367.             case END:
  368.                 cursorOFF();
  369.                 con_str1(q);
  370.                 cursorON();
  371.                 q += strlen(q);
  372.                 break;
  373.  
  374.             case BACKDEL:
  375.                 if (q > p + 1)
  376.                 {
  377.                     cursorLEFT();
  378.                     storeXY(&x, &y);
  379.                     strcpy(q-1, q);
  380.                     q--;
  381.                     cursorOFF();
  382.                     con_str1(q);
  383.                     con_chr(' ');
  384.                     gotoXY(x, y);
  385.                     cursorON();
  386.                 }
  387.                 break;
  388.  
  389.             case FORWDEL:
  390.                 if (*q != '\0')
  391.                 {
  392.                     storeXY(&x, &y);
  393.                     strcpy(q, q + 1);
  394.                     cursorOFF();
  395.                     con_str1(q);
  396.                     con_chr(' ');
  397.                     gotoXY(x, y);
  398.                     cursorON();
  399.                 }
  400.                 break;
  401.  
  402.             case CLEAR:
  403.                 e = q - p - 1;
  404.                 cursorOFF();
  405.                 for(i = 0; i < e; i++)
  406.                     cursorLEFT();
  407.  
  408.                 storeXY(&x, &y);
  409.  
  410.                 q = p + 1;
  411.  
  412.                 e = strlen(q);
  413.  
  414.                 for (i = 0; i < e; i++)
  415.                     con_chr(' ');
  416.  
  417.                 gotoXY(x, y);
  418.                 cursorON();
  419.  
  420.                 *q = '\0';
  421.                 break;
  422.  
  423.             case KILL:
  424.                 if (*q != '\0')
  425.                 {
  426.                     storeXY(&x, &y);
  427.                     cursorOFF();
  428.                     e = strlen(q);
  429.                     for (i = 0; i < e; i++)
  430.                         con_chr(' ');
  431.                     *q = '\0';
  432.                     gotoXY(x, y);
  433.                     cursorON();
  434.                 }
  435.                 break;
  436.  
  437.             case INSERT:
  438.                 imode = !imode;
  439.                 break;
  440.  
  441.             case FPROG:
  442.                 if(!fprog)
  443.                 {
  444.                     fprog = 1;
  445.                     cursorOFF();
  446.                     storeXY(&x, &y);
  447.                     gotoXY(0, 0);
  448.                     reverseON();
  449.                     for (i = 0; i < screen->width; i++)
  450.                         con_chr(' ');
  451.                     gotoXY(0, 0);
  452.                     con_str1("Press function key: ");
  453.                     cursorON();
  454.                     con_flush();
  455.                     do
  456.                         c = con_getc();
  457.                     while(c < FSTART);
  458.                     cursorOFF();
  459.                     gotoXY(0, 0);
  460.                     con_str1("Enter text:                     ");
  461.                     gotoXY(12, 0);
  462.                     fbuf[0] = 17;
  463.                     cursorON();
  464.                     con_flush();
  465.                     read_str(fbuf, &fhist);
  466.                     cursorOFF();
  467.                     status();
  468.                     gotoXY(x, y);
  469.                     cursorON();
  470.                     strcpy(fkeys[c - FSTART], fbuf + 1);
  471.                     fprog = 0;
  472.                 }
  473.                 break;
  474.  
  475.             default:
  476.                 if (strlen(p + 1) < p[0] || (*q && !imode))
  477.                 {
  478.                     if (c >= ' ' && c < 0x80)
  479.                     {
  480.                         if (imode)
  481.                         {
  482.                             for (src = q + strlen(q),
  483.                                 dst = q + strlen(q) + 1;
  484.                                 src >= q;
  485.                                 *dst-- = *src--)
  486.                                 ;
  487.                             *q = c;
  488.                             cursorOFF();
  489.                             con_str1(q++);
  490.                             e = strlen(q);
  491.                             for(i = 0; i < e; i++)
  492.                                 cursorLEFT();
  493.                             cursorON();
  494.                         }
  495.                         else
  496.                         {
  497.                             if (!*q)
  498.                                 *(q+1) = '\0';
  499.                             *q++ = c;
  500.                             con_chr(c);
  501.                         }
  502.                     }
  503.                     else if (c >= FSTART)
  504.                     {
  505.                         if (!*q)
  506.                         {
  507.                             strncpy(q, fkeys[c - FSTART], end - q);
  508.                             cursorOFF();
  509.                             con_str1(q);
  510.                             cursorON();
  511.                             q += strlen(q);
  512.                         }
  513.                         else if (imode)
  514.                         {
  515.                             if (end - q - strlen(q) < strlen(fkeys[c - FSTART]))
  516.                                 dst = end + 1;
  517.                             else
  518.                                 dst = q + strlen(fkeys[c - FSTART]) + strlen(q) + 1;
  519.  
  520.                             cursorOFF();
  521.                             for (src = q + strlen(q) + 1; src >= q; *dst-- = *src--)
  522.                                 ;
  523.  
  524.                             for(src = fkeys[c - FSTART]; q <= dst;)
  525.                                 con_chr(*q++ = *src++);
  526.  
  527.                             con_str1(q);
  528.                             e = strlen(q);
  529.                             for(i = 0; i < e; i++)
  530.                                 cursorLEFT();
  531.                             cursorON();
  532.                         }
  533.                         else
  534.                         {
  535.                             if(strlen(q) < strlen(fkeys[c - FSTART]))
  536.                             {
  537.                                 strncpy(q, fkeys[c - FSTART], end - q);
  538.                                 dst = q + strlen(fkeys[c - FSTART]);
  539.                                 dst = (dst < end)?dst:end;
  540.                             }
  541.                             else
  542.                             {
  543.                                 for(src = fkeys[c - FSTART], dst = q; *src && dst < end; *dst++ = *src++)
  544.                                     ;
  545.                             }
  546.                             cursorOFF();
  547.                             con_str2(q, dst);
  548.                             cursorON();
  549.                             q = dst;
  550.                         }
  551.                     }
  552.                 }
  553.         }
  554.         con_flush();
  555.     }
  556.  
  557.     (*p)++;        /* restore original maxlen    */
  558.  
  559.     if (!retype)
  560.         retype = hist->undo;
  561.  
  562.     if (strcmp(retype, p + 1) && strlen(p + 1))
  563.     {
  564.         for (src = hist->hb + hist->len - strlen(p + 1) - 2,
  565.           dst = hist->hb + hist->len - 1;
  566.             src >= hist->hb; *dst-- = *src--)
  567.             ;
  568.  
  569.         strcpy(hist->hb, p + 1);
  570.  
  571.         hist->hb[hist->len - 2] = hist->hb[hist->len - 1] = '\0';
  572.         hist->undo = hist->hb;
  573.     }
  574.     else
  575.         hist->undo = retype;
  576.  
  577.     cursorOFF();
  578.     con_str1(q);
  579.     cursorON();
  580.     putc_dev('\n', screen);
  581.     con_flush();
  582.     return(p + strlen(p + 1) + 1);
  583. }
  584.